package com.x.xiaoshuo.widget;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;

import java.util.ArrayList;

public class PercentDrawable extends Drawable {
    Paint bgPaint = new Paint();
    ArrayList<Paint> contentPaints = new ArrayList<>();
    ArrayList<Paint> dotPaints = new ArrayList<>();
    int cellSize;
    int cellWidth;
    float[] values;
    RectF dot;
    RectF rect;
    float startAngle;

    public PercentDrawable(int cellWidth, int bgColor) {
        this.cellWidth = cellWidth;
        bgPaint.setColor(bgColor);
        bgPaint.setStrokeWidth(cellWidth);
        bgPaint.setStyle(Paint.Style.STROKE);
        bgPaint.setAntiAlias(true);
    }

    public void setCellSize(int cellSize) {
        this.cellSize = cellSize;
        rect = new RectF(0 + cellWidth, 0 + cellWidth, cellSize - cellWidth, cellSize - cellWidth);
        startAngle = getStartAngle();
        createDot();
    }

    private float getStartAngle() {
        float dotR = cellWidth / 2;
        float r = (cellSize - cellWidth) / 2;
        return (float) (Math.atan(dotR / (r - dotR)) / Math.PI * 180);
    }

    public void setContentColors(int[] colors, float[] values) {
        if (colors == null || values == null || colors.length != values.length) {
            return;
        }
        if (colors != null) {
            for (int i = 0; i < colors.length; i++) {
                if (i >= contentPaints.size()) {
                    Paint paint = new Paint();
                    paint.setColor(colors[i]);
                    paint.setStrokeWidth(cellWidth);
                    paint.setStyle(Paint.Style.STROKE);
                    paint.setAntiAlias(true);
                    contentPaints.add(paint);
                    Paint dotPaint = new Paint();
                    dotPaint.setAntiAlias(true);
                    dotPaint.setColor(colors[i]);
                    dotPaint.setStrokeWidth(0);
                    dotPaint.setStyle(Paint.Style.FILL);
                    dotPaints.add(dotPaint);

                } else {
                    contentPaints.get(i).setColor(colors[i]);
                    dotPaints.get(i).setColor(colors[i]);
                }
            }
        }
        this.values = values;
    }

    public void setContentColors(int[] colors) {
        if (colors == null) {
            return;
        }
        if (colors != null) {
            for (int i = 0; i < colors.length; i++) {
                if (i >= contentPaints.size()) {
                    Paint paint = new Paint();
                    paint.setColor(colors[i]);
                    paint.setStrokeWidth(cellWidth);
                    paint.setStyle(Paint.Style.STROKE);
                    paint.setAntiAlias(true);
                    contentPaints.add(paint);
                    Paint dotPaint = new Paint();
                    dotPaint.setAntiAlias(true);
                    dotPaint.setColor(colors[i]);
                    dotPaint.setStrokeWidth(0);
                    dotPaint.setStyle(Paint.Style.FILL);
                    dotPaints.add(dotPaint);

                } else {
                    contentPaints.get(i).setColor(colors[i]);
                    dotPaints.get(i).setColor(colors[i]);
                }
            }
        }
    }

    public void setValues(float[] values) {
        if (values == null || values.length != contentPaints.size()) {
            return;
        }
        this.values = values;
    }

    private void createDot() {
        dot = new RectF((cellSize - cellWidth) / 2, cellWidth / 2 + 1, (cellSize + cellWidth) / 2, cellWidth + cellWidth / 2);
    }

    RectF getDot(float angle) {
        if (angle >= startAngle) {
            return dot;
        } else {
            float width = (float) (cellSize / 2 * Math.sin(2 * Math.PI / 360 * angle));
            RectF rectF = new RectF(cellSize / 2 - width, cellWidth / 2 + 1, cellSize / 2 + width, cellWidth + cellWidth / 2);
            return rectF;
        }
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawArc(rect, 0f, 360f, false, bgPaint);
        canvas.save();
        canvas.rotate(270f, cellSize / 2, cellSize / 2);
        canvas.drawArc(rect, 0f, 90f, false, bgPaint);
        drawValue(canvas);
        canvas.restore();
        canvas.save();

        for (int i = 0; i < dotlist.size(); i++) {
            canvas.rotate(dotlist.get(i), cellSize / 2, cellSize / 2);
            canvas.drawOval(dots.get(i), dotPaints.get(printInx.get(i)));
        }


        canvas.restore();
    }

    ArrayList<Float> dotlist = new ArrayList<>();
    ArrayList<RectF> dots = new ArrayList<>();
    ArrayList<Integer> printInx = new ArrayList<>();

    private void addDot(float angle, float dotAngle, int inx) {
        dotlist.add(angle);
        dots.add(getDot(dotAngle));
        printInx.add(inx);
    }

    private void clearDot() {
        dotlist.clear();
        dots.clear();
        printInx.clear();
    }

    private void drawValue(Canvas canvas) {
        clearDot();
        float start = 0;
        float oangle = 0;
        float angle;
        for (int i = 0; i < contentPaints.size(); i++) {
            float sweep = 360f * values[i];
            if (sweep == 360f) {
                canvas.drawArc(rect, 0, 360, false, contentPaints.get(i));
                clearDot();
                break;
            }
            if (sweep < startAngle * 2) {
                angle = sweep / 2;
                start += sweep;
                if (angle != 0) {
                    addDot(oangle + angle, angle, i);
                    if (oangle != 0) {
                        canvas.drawArc(rect, start - oangle, oangle, false, contentPaints.get(i));
                    }
                }
                oangle = angle;
                continue;
            } else {
                angle = startAngle;
            }
            if (i == 0) {
                addDot(angle, angle, i);
                addDot(sweep - angle * 2, angle, i);
                canvas.drawArc(rect, start + angle, sweep - angle * 2, false, contentPaints.get(i));
            } else {
                addDot(sweep - (angle - oangle), angle, i);
                canvas.drawArc(rect, start - oangle, sweep - (angle - oangle), false, contentPaints.get(i));
            }
            oangle = angle;
            start += sweep;
        }
    }

    @Override
    public void setAlpha(int alpha) {

    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return PixelFormat.UNKNOWN;
    }

    @Override
    public int getIntrinsicWidth() {
        return cellSize;
    }

    @Override
    public int getIntrinsicHeight() {
        return cellSize;
    }
}
